﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class Cell : MonoBehaviour {
	[Tooltip("生成细胞消耗的能量")]
	public int ConsumedEnergy;
	[Tooltip("细胞的寿命，单位为周期")]
	public int LifeTime;
	[Tooltip("细胞移动的速度")]
	public float Speed;
	[Tooltip("最终目标的Tag")]
	public string TargetTag;
   
    [Tooltip("检测目标的范围大小")]
	public float DetectRange;
	[Tooltip("攻击范围大小")]
	public float AttackRange;
    [Tooltip("遇到障碍的旋转范围")]
    public float RotateSpeed=10;
    [Tooltip("向目标的旋转速度")]
    public float RotateSpeed2=100;
     [Tooltip("漫游更换方向的间隔")]
    public float wanderTimerSpace=3.0f;
    float wanderTimer = 3.0f; //更换随机方向的时间
    Vector2 randomDirection = Vector2.left;

    private UnityAction m_Action;
    private int m_CurrentInterval;
    
    public delegate void ProcessTarget(GameObject target);
    private void Awake() {
        GetRandomDirection();

        m_Action += Tick;
        m_CurrentInterval = 0;
        GameController.Instance.AddTickEvent(m_Action);
        /*Animation animation = GetComponent<Animation>();
        if(animation != null) {
            animation.Play("CellIdle");
        }*/
    }
    // 更新正在追踪的目标
    public GameObject UpdateTarget(ProcessTarget process) {
        GameObject target = null;
        // RaycastHit2D[] rh = Physics2D.CircleCastAll(transform.position, DetectRange, transform.up, 0);
        // float Dmin = 9999;
        // if (rh != null) {
        //     foreach (RaycastHit2D hit in rh) {
        //         if (hit.collider.tag == TargetTag) {
        //             Vector3 dir = hit.collider.gameObject.transform.position - transform.position;

        //             if (Dmin >= dir.magnitude) {
        //                 Dmin = dir.magnitude;

        //                 target = hit.collider.gameObject;
        //                 if (dir.magnitude < AttackRange) {
        //                     process(target);
        //                 }
        //             }
        //         }
        //     }
        // }

        Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, DetectRange);
        float distance = 9999;
        if(colliders != null) {

            foreach (var item in colliders) {
                if (item.tag == TargetTag) {
                    Vector3 dir = item.gameObject.transform.position - transform.position;

                    if (distance >= dir.magnitude) {
                        distance = dir.magnitude;

                        target = item.gameObject;
                        if (dir.magnitude < AttackRange) {
                            if (this.gameObject.activeSelf==true) {
                                // Debug.Log(this.gameObject.transform.position);
                                process(target);
                            }
                           
                        }
                    }
                }
            }
        }
        return target;
	}

    private void Tick() {
        m_CurrentInterval ++;

        if(m_CurrentInterval == LifeTime) {
            GameController.Instance.RemoveTickEvent(m_Action);
            Destroy(this.gameObject);
        }
    }

    // 追踪目标
    public void FollowTarget(GameObject enemy)
    {
        //   float speed=1;
       
        // Quaternion targetAngels;
        Vector3 direction = enemy.transform.position - transform.position;
        Move(direction);
    }

	private void TurnAround(float speed) {
		Quaternion targetAngels;
		 //躲避障碍
        
        targetAngels = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + 30f);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetAngels, speed * Time.deltaTime);
	}

	// 移动函数
	private void Move(Vector3 direction) {
        float angle = Vector2.SignedAngle(transform.up.normalized, direction.normalized);
        RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.up, 3, 1 << LayerMask.NameToLayer("obstacle"));
        if (hit) {
			// 躲避障碍
            TurnAround(RotateSpeed);
		} else {
            //向目标旋转
         
            if (angle < 0)
            {
                transform.Rotate(Vector3.back * Time.deltaTime * RotateSpeed2);

            }
            else
            {
                transform.Rotate(Vector3.forward * Time.deltaTime * RotateSpeed2);
            }
        }
        //前进
        this.transform.position += transform.up * Speed * Time.deltaTime;
    }

    // 随机移动
    public void Wander() {
        if(wanderTimer <= 0) {
            GetRandomDirection();
            wanderTimer = wanderTimerSpace;
        }
        wanderTimer -= Time.deltaTime;
        Move(randomDirection);
	}
    public void MoveAway() {
        if(wanderTimer <= 0) {
            GetRandomDirection(true);
            wanderTimer = wanderTimerSpace;
        }
        wanderTimer -= Time.deltaTime;
        Move(randomDirection);
	}
    public void GetRandomDirection(bool isAway = false) {
        if(isAway == false) {
            float xDir = Random.Range(-1f,1f);
            float yDir = Random.Range(-1f,1f); 
            randomDirection = new Vector3(xDir, yDir, 0);
            return;
        }
        int organNum = CellController.Instance.organizes.Count;
        //Vector2[] dirReverse = new Vector2[organNum];
        Vector2 myPos = new Vector2(transform.position.x,transform.position.y);
        Vector2 dirSum =Vector2.zero;
        float dirReverseSum = 0;

        for(int i = 0; i < organNum; ++i) {
            float distance = (myPos - CellController.Instance.organizes[i]).magnitude;
            float distanceReverse;
            if(distance > 0) 
                distanceReverse = 1f / distance;
            else 
                distanceReverse = 1f / 0.001f;          
            dirSum += (myPos - CellController.Instance.organizes[i]).normalized * distanceReverse; //organ point to myPos.
            dirReverseSum += distanceReverse;
        }
        Vector2 dirNormalize = dirSum.normalized;
        randomDirection = new Vector3(dirNormalize.x, dirNormalize.y, 0);
        float angle = Vector2.SignedAngle(Vector3.up, randomDirection);
        transform.localEulerAngles = new Vector3(0, 0, angle);
        
        Debug.Log(randomDirection.x + " " +randomDirection.y);
    }
}
